import * as vscode from 'vscode';
import { ScanResult } from './scanner';
import { AIResult } from './ai';

export function showScanResultsWebview(semgrepResults: ScanResult[], aiResults: AIResult[], filePath?: string) {
  const panel = vscode.window.createWebviewPanel(
    'scanResults',
    '漏洞扫描结果',
    vscode.ViewColumn.Beside,
    { enableScripts: true }
  );
  panel.webview.html = getWebviewContent(semgrepResults, aiResults, filePath);
  // 监听Webview消息，实现跳转和修复
  panel.webview.onDidReceiveMessage(msg => {
    if (msg.command === 'jumpToLine' && typeof msg.line === 'number') {
      const editor = vscode.window.activeTextEditor;
      if (editor) {
        const pos = new vscode.Position(msg.line - 1, 0);
        editor.revealRange(new vscode.Range(pos, pos), vscode.TextEditorRevealType.InCenter);
        editor.selection = new vscode.Selection(pos, pos);
      }
    }
    if (msg.command === 'applyFix' && typeof msg.line === 'number' && typeof msg.fix === 'string') {
      const editor = vscode.window.activeTextEditor;
      if (editor) {
        editor.edit(editBuilder => {
          const line = msg.line - 1;
          editBuilder.replace(editor.document.lineAt(line).range, msg.fix);
        });
        const pos = new vscode.Position(msg.line - 1, 0);
        editor.selection = new vscode.Selection(pos, pos);
        editor.revealRange(new vscode.Range(pos, pos), vscode.TextEditorRevealType.InCenter);
      }
    }
    if (msg.command === 'applyAllFixes' && Array.isArray(msg.fixes)) {
      const editor = vscode.window.activeTextEditor;
      if (editor) {
        editor.edit(editBuilder => {
          msg.fixes.forEach((fix: { line: number, fix: string }) => {
            const line = fix.line - 1;
            editBuilder.replace(editor.document.lineAt(line).range, fix.fix);
          });
        });
      }
    }
    if (msg.command === 'exportJson' && msg.filePath && msg.data) {
      const outPath = msg.filePath + '.scan.json';
      require('fs').writeFileSync(outPath, JSON.stringify(msg.data, null, 2));
      vscode.window.showInformationMessage('扫描结果已导出: ' + outPath);
    }
  });
}

function getWebviewContent(semgrepResults: ScanResult[], aiResults: AIResult[], filePath?: string): string {
  return `
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <style>
        body { font-family: sans-serif; }
        .section { margin-bottom: 24px; }
        .vuln { margin: 6px 0; padding: 6px; border-bottom: 1px solid #eee; cursor: pointer; }
        .ai { color: #b35c00; }
        .rule { color: #005cb3; }
        .line { font-weight: bold; }
        .fix-btn { margin-left: 10px; padding: 2px 8px; }
      </style>
    </head>
    <body>
      <h2>规则检测结果（${semgrepResults.length}）</h2>
      <div class="section">
        ${semgrepResults.map(r => `<div class="vuln rule" data-line="${r.line}">[${r.ruleId}] ${r.message} <span class="line">(行${r.line})</span> ${r.message.includes('input') ? `<button class='fix-btn' onclick='applyFix(${r.line}, "sanitize(input)")'>应用修复</button>` : ''}</div>`).join('') || '<div>无</div>'}
      </div>
      <h2>AI增强检测结果（${aiResults.length}）</h2>
      <div class="section">
        ${aiResults.map(r => `<div class="vuln ai" data-line="${r.line}">[${r.riskType || 'AI'}] ${r.message} <span class="line">(行${r.line})</span>${r.suggestion ? `<br/><b>修复建议：</b>${r.suggestion} <button class='fix-btn' onclick='applyFix(${r.line}, \
          "${r.suggestion.replace(/"/g, '\\"')}"\
        )'>应用修复</button>` : ''}</div>`).join('') || '<div>无</div>'}
      </div>
      <button onclick="window.open('https://wj.qq.com/s/xxxxxxx')">反馈建议</button>
      <button onclick="applyAllFixes()">批量应用所有修复</button>
      <button onclick="exportJson()">导出JSON</button>
      <script>
        document.querySelectorAll('.vuln').forEach(el => {
          el.addEventListener('click', () => {
            const line = parseInt(el.getAttribute('data-line'));
            if (!isNaN(line)) {
              if (window.acquireVsCodeApi) {
                window.acquireVsCodeApi().postMessage({ command: 'jumpToLine', line });
              }
            }
          });
        });
        window.applyFix = function(line, fix) {
          if (window.acquireVsCodeApi) {
            window.acquireVsCodeApi().postMessage({ command: 'applyFix', line, fix });
          }
        }
        window.applyAllFixes = function() {
          const fixes = [];
          document.querySelectorAll('.fix-btn').forEach(btn => {
            const line = parseInt(btn.closest('.vuln').getAttribute('data-line'));
            const fix = btn.getAttribute('onclick').match(/,\s*\"(.+)\"\)/)[1];
            fixes.push({ line, fix });
          });
          if (window.acquireVsCodeApi) {
            window.acquireVsCodeApi().postMessage({ command: 'applyAllFixes', fixes });
          }
        }
        window.exportJson = function() {
          if (window.acquireVsCodeApi) {
            window.acquireVsCodeApi().postMessage({ command: 'exportJson', filePath: '${filePath}', data: { semgrepResults: ${JSON.stringify(semgrepResults)}, aiResults: ${JSON.stringify(aiResults)} } });
          }
        }
      </script>
    </body>
    </html>
  `;
} 